<!DOCTYPE html>
<html lang="cn">

<head>
    <meta charset="UTF-8">
    <title>加密通信</title>
    <!-- 引用vue和elementUI-->
    <!-- <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <script src="https://unpkg.com/element-ui/lib/index.js"></script> -->
    <link rel="stylesheet" href="./js/index.css">
    <script src="./js/vue.js"></script>
    <script src="./js/index.js"></script>
    <script src="./js/axios.min.js"></script>
</head>

<body>
<div id="app">
    <el-container>
        <el-header style="height: auto;">
            <el-row>
                <el-col :span="24">
                    <el-radio-group v-model="currentKey" @change="tran">
                        <el-radio-button v-for="(item ,index) in encryptKeyList" :label="item" :key="'key_'+index">
                            {{item}}
                        </el-radio-button>
                    </el-radio-group>

                </el-col>
            </el-row>

            <el-row>
                <el-col :span="12">
                    <el-input v-model="newKey" size="medium" @keyup.enter.native="saveNewKey" :key="9008"
                              style="width: 70%;"
                              placeholder="请输入自定义加密文字...">
                        <el-button slot="append" icon="el-icon-plus" @click="saveNewKey"></el-button>
                    </el-input>
                    <el-button @click="clearStorage" type="success">清空</el-button>
                </el-col>

                <el-col :span="1" :offset="9">
                    <el-popover
                            placement="bottom"
                            width="160"
                            v-model="settingVisible">
                        <el-form ref="form" label-width="100px">
                            <el-form-item label="自动复制开关">
                                <el-switch v-model="autoCopyStatus" active-color="#13ce66"
                                           @change="autoCopyChange"
                                           inactive-color="#ff4949">
                                </el-switch>
                            </el-form-item>
                            <el-form-item label="自动复制延时">
                                <el-slider :step="0.1" :min="0.1" :max="4" v-model="autoCopyTime" :format-tooltip="formatTooltip" @change="autoCopyTimeChange">
                                </el-slider>
                            </el-form-item>
                        </el-form>
                        <el-button icon="el-icon-s-tools" circle slot="reference" plain></el-button>
                    </el-popover>
                </el-col>
            </el-row>
        </el-header>
        <el-main>
            <el-row :gutter="20">
                <el-col :span="10">
                    <el-card>
                        <el-input type="textarea" resize="none" :rows="10" placeholder="请输入内容" v-model="input"
                                  @input="tran">
                        </el-input>
                    </el-card>
                </el-col>
                <el-col :span="2" class="middle-box">
                    <el-button circle title="翻译" class="middle-box-button transition-button" @click="tran"></el-button>
                    <el-button circle icon="el-icon-copy-document" title="复制" class="middle-box-button" type="info"
                               @click="copy"></el-button>
                </el-col>
                <el-col :span="10">
                    <el-card>
                        <el-input type="textarea" resize="none" :rows="10" placeholder="请输入内容" v-model="output"
                                  :readonly="true">
                        </el-input>
                    </el-card>
                </el-col>
            </el-row>
        </el-main>
    </el-container>
</div>
<script type="text/javascript">
  const ENCRYPT_CODE = [
    "歪比吧卜",
    "啊吧阿巴",
    "之乎者也",
    "张三李四王二麻子小淘气"
  ]
  const vm = new Vue({
    el: '#app',
    data() {
      return {
        lastTime: 0,
        copyTime: 0,
        input: "",
        output: "",
        encryptKeyList: [],
        customKey: [],
        currentKey: "",
        newKey: "",
        autoCopyStatus: true,
        autoCopyTime: 1.5,
        encryptKeyListRev: undefined,
        autoCopyStatusRev: undefined,
        autoCopyTimeRev: undefined,
        settingVisible: false,
      }
    },
    computed: {
      regExpList() {
        return this.encryptKeyList.map(item => {
          let itemArray = Array.from(item)
          itemArray.pop()
          let reg = `^([${itemArray.join("")}]+${item.charAt(item.length - 1)})+$`
          return new RegExp(reg, "i")
        })
      }
    },
    created() {
      this.init()
      //初始化加密秘钥组
      let customKey = utools?.db.get("encryptKey")?.data || []
      this.encryptKeyList.push(...customKey)
      this.currentKey = this.encryptKeyList[0]

      let autoCopyStatus = utools?.db.get("autoCopyStatus")?.data
      console.log("get from db, auto copy status = ", utools?.db.get("autoCopyStatus")?.data)
      this.autoCopyStatus = autoCopyStatus === "0" ? false : true;

      let autoCopyTime = utools?.db.get("autoCopyTime")?.data || 1.5
      console.log("get from db, auto copy time = ", utools?.db.get("autoCopyTime"))
      this.autoCopyTime = autoCopyTime
    },
    methods: {
      init() {
        this.encryptKeyList.length = 0
        this.encryptKeyList.push(...ENCRYPT_CODE)
      },
      format(keyStr) {
        let returnStr;
        //校验是否有重复字符
        let distinctReg = /([\S]).*\1/;
        if (distinctReg.test(keyStr)) returnStr = "加密字符有重复文字"
        else if (this.encryptKeyList.indexOf(keyStr) > -1) returnStr = "加密字符已存在，不要重复添加"
        return returnStr;
      },
      encrypt(text = this.input, dic = this.currentKey) {
        //加密函数
        const splitChar = dic.charAt(dic.length - 1)
        console.log("加密文本：{}，加密key：{}，切割符：{}", text, dic, splitChar)
        //将Unicode的进制转后的值，转为加密字符
        const encryptUnicode = c => Array.from(c).map(i => dic[i]).join("")
        this.output = Array.from(text).map(t => {
          let unicodeValue = t.charCodeAt(0).toString(dic.length - 1)
          return encryptUnicode(unicodeValue) + splitChar
        }).join("")
      },
      decrypt(text = this.input, dic = this.currentKey) {
        // 开始解密
        const splitChar = dic.charAt(dic.length - 1)
        console.log("加解文本：{}，加密key：{}，切割符：{}", text, dic, splitChar)
        //将切割后的每个连续的字符串转换为一个字符的Unicode值
        const convert2UniCode = txt => {
          let keyArray = Array.from(dic).map((item, index) => [item, index.toString()]);
          let dic1 = Object.fromEntries(keyArray)
          return Array.from(txt).map(t => dic1[t] || "").join("")
        }
        let arr = text.split(splitChar)
        arr.pop()
        this.output = arr.map(character => {
          let code = parseInt(convert2UniCode(character) || 0, dic.length - 1)
          return String.fromCharCode(code)
        }).join("")
      },
      tran() {
        /*
            自动判断入口（已进行节流处理）<br/>
            判断字符正则，是否为加密串<br/>
            如果为加密串，则进行解密，否则对其进行加密<br/>
         */

        let f = () => {
          let index = this.regExpList.findIndex(reg => {
            return reg.test(this.input)
          })
          if (index !== -1) {
            this.decrypt(this.input, this.encryptKeyList[index]);
          } else {
            this.encrypt(this.input, this.currentKey);
          }
        }
        if (this.lastTime) {
          clearTimeout(this.lastTime)
        }
        if (this.copyTime) {
          clearTimeout(this.copyTime)
        }
        if (!this.input) {
          this.output = ""
          return
        }
        this.lastTime = setTimeout(f, 500)
        if (this.autoCopyStatus) {
          this.copyTime = setTimeout(this.copy, this.autoCopyTime * 1000)
        }
      },
      copy() {
        if (utools) {
          utools?.copyText(this.output)
        } else {
          let transfer = document.createElement('input');
          document.body.appendChild(transfer);
          transfer.value = this.output;
          transfer.focus();
          transfer.select();
          if (document.execCommand('copy')) {
            document.execCommand('copy');
          }
          transfer.blur();
          document.body.removeChild(transfer);
        }
        window.utools?.copyText(this.output)
        this.$notify.info({
          title: 'Info',
          message: '已成功复制到剪切板',
          showClose: false,
          duration: 800
        });
        // this.$message('已成功复制到剪切板');
      },
      saveNewKey() {
        if (this.newKey) {
          let formatRes = this.format(this.newKey);
          if (formatRes) {
            this.$notify.error({
              title: 'error',
              message: formatRes,
              showClose: false,
              duration: 800
            });
            return;
          }
          // 执行存储逻辑
          this.encryptKeyList.push(this.newKey)
          let customKey = utools?.db.get("encryptKey")?.data || []
          customKey.push(this.newKey)
          let params = {
            _id: "encryptKey",
            data: customKey
          }
          if (this.encryptKeyListRev) {
            params._rev = this.encryptKeyListRev
          }
          let res = utools?.db.put(params)
          if (res && res.ok) {
            this.encryptKeyListRev = res.rev;
          } else {
            utools?.db.remove("encryptKey")
          }
          this.$notify.success({
            title: 'Info',
            message: '添加成功',
            showClose: false,
            duration: 800
          });
          this.newKey = ''
        }
      },
      clearStorage() {
        console.log(this.autoCopyTime);
        utools?.db.remove("encryptKey")
        this.init()
        this.$notify.success({
          title: 'Info',
          message: '已清空自定义加密文字',
          showClose: false,
          duration: 800
        });
      },
      //滑块格式化
      formatTooltip(val) {
        return `${val}秒`;
      },
      autoCopyChange() {
        console.log("是否自动存储", this.autoCopyStatus ? "是" : "否")
        let params = {
          _id: "autoCopyStatus",
          data: this.autoCopyStatus ? "1" : "0"
        }
        if (this.autoCopyStatusRev) {
          params._rev = this.autoCopyStatusRev
        }
        let res = utools?.db.put(params)
        console.log(res)
        if (res && res.ok) {
          this.autoCopyStatusRev = res.rev;
        } else {
          utools?.db.remove("autoCopyStatus")
        }
      },
      autoCopyTimeChange() {
        console.log("自动复制延时：", this.autoCopyTime)
        let params = {
          _id: "autoCopyTime",
          data: this.autoCopyTime
        }
        if (this.autoCopyTimeRev) {
          params._rev = this.autoCopyTimeRev
        }
        let res = utools?.db.put(params)
        console.log(res)
        if (res && res.ok) {
          this.autoCopyTimeRev = res.rev;
        } else {
          utools?.db.remove("autoCopyTime")
        }
      }
    }
  })
</script>
<style>
    .el-button + .el-button {
        margin-left: 0px;
    }

    .transition-button {
        background: url("./assets/cat.gif");
        width: 44px;
        height: 44px;
        background-repeat: no-repeat;
        background-position: center;
        background-size: 100% 100%;

    }

    .middle-box-button:first-child {
        margin-top: 9vh;
    }

    .middle-box {
        float: left;
        writing-mode: vertical-lr;
    }

    .el-row {
        margin-bottom: 20px;
    }

    .el-col {
        border-radius: 4px;
    }

    .bg-purple-dark {
        background: #99a9bf;
    }

    .bg-purple {
        background: #d3dce6;
    }

    .bg-purple-light {
        background: #e5e9f2;
    }

    .grid-content {
        border-radius: 4px;
        min-height: 36px;
    }

    .row-bg {
        padding: 10px 0;
        background-color: #f9fafc;
    }

    .text {
        font-size: 14px;
    }

    .item {
        padding: 18px 0;
    }

    .box-card {
        width: 480px;
    }
</style>

</body>

</html>
